// This is an open source non-commercial project. Dear PVS-Studio, please check it.
// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com

// ReSharper disable CheckNamespace
// ReSharper disable CommentTypo
// ReSharper disable InconsistentNaming

/* MajorTic.cs --
 * Ars Magna project, http://arsmagna.ru
 */

#region Using directives

using System;
using System.Drawing;
using System.Runtime.Serialization;

#endregion

#nullable enable

namespace AM.Drawing.Charting;

/// <summary>
/// Class that holds the specific properties for the major tics.  Inherits from
/// <see cref="MinorTic" />.
/// </summary>
[Serializable]
public class MajorTic
    : MinorTic, ICloneable
{
    internal bool _isBetweenLabels;

    #region Constructors

    /// <summary>
    /// Default constructor for <see cref="MajorTic" />.
    /// </summary>
    public MajorTic()
    {
        _size = Default.Size;
        _color = Default.Color;
        _penWidth = Default.PenWidth;

        IsOutside = Default.IsOutside;
        IsInside = Default.IsInside;
        IsOpposite = Default.IsOpposite;
        _isCrossOutside = Default.IsCrossOutside;
        _isCrossInside = Default.IsCrossInside;

        _isBetweenLabels = false;
    }

    /// <summary>
    /// Copy constructor.
    /// </summary>
    /// <param name="rhs">The <see cref="MajorTic" /> that is to be copied.</param>
    public MajorTic (MajorTic rhs)
        : base (rhs)
    {
        _isBetweenLabels = rhs._isBetweenLabels;
    }

    /// <summary>
    /// Implement the <see cref="ICloneable" /> interface in a typesafe manner by just
    /// calling the typed version of <see cref="Clone" />
    /// </summary>
    /// <returns>A deep copy of this object</returns>
    object ICloneable.Clone()
    {
        return Clone();
    }

    /// <summary>
    /// Typesafe, deep-copy clone method.
    /// </summary>
    /// <returns>A new, independent copy of this class</returns>
    public new MajorTic Clone()
    {
        return new MajorTic (this);
    }

    #endregion

    #region Properties

    /// <summary>
    /// Gets or sets a property that determines whether or not the major tics will be drawn
    /// inbetween the labels, rather than right at the labels.
    /// </summary>
    /// <remarks>
    /// Note that this setting is only
    /// applicable if <see cref="Axis.Type"/> = <see cref="AxisType.Text"/>.
    /// </remarks>
    /// <value>true to place the text between the labels for text axes, false otherwise</value>
    /// <seealso cref="MinorTic.IsOutside"/>
    /// <seealso cref="MinorTic.IsInside"/>
    /// <seealso cref="MinorTic.IsOpposite"/>
    /// <seealso cref="MinorTic.IsCrossOutside"/>
    /// <seealso cref="MinorTic.IsCrossInside"/>
    public bool IsBetweenLabels
    {
        get { return _isBetweenLabels; }
        set { _isBetweenLabels = value; }
    }

    #endregion

    #region Serialization

    /// <summary>
    /// Current schema value that defines the version of the serialized file
    /// </summary>
    public const int schema2 = 10;

    /// <summary>
    /// Constructor for deserializing objects
    /// </summary>
    /// <param name="info">A <see cref="SerializationInfo"/> instance that defines the serialized data
    /// </param>
    /// <param name="context">A <see cref="StreamingContext"/> instance that contains the serialized data
    /// </param>
    protected MajorTic
        (
            SerializationInfo info,
            StreamingContext context
        )
        : base (info, context)
    {
        // The schema value is just a file version parameter.  You can use it to make future versions
        // backwards compatible as new member variables are added to classes
        info.GetInt32 ("schema2").NotUsed();

        _isBetweenLabels = info.GetBoolean ("isBetweenLabels");
    }

    /// <inheritdoc cref="ISerializable.GetObjectData"/>
    public override void GetObjectData
        (
            SerializationInfo info,
            StreamingContext context
        )
    {
        base.GetObjectData (info, context);

        info.AddValue ("schema2", schema2);
        info.AddValue ("isBetweenLabels", _isBetweenLabels);
    }

    #endregion

    #region Defaults

    /// <summary>
    /// A simple struct that defines the
    /// default property values for the <see cref="MinorTic"/> class.
    /// </summary>
    public new struct Default
    {
        // Default Axis Properties
        /// <summary>
        /// The default size for the <see cref="Axis"/> tic marks.
        /// (<see cref="MinorTic.Size"/> property). Units are in points (1/72 inch).
        /// </summary>
        public static float Size = 5;

        /// <summary>
        /// The default pen width for drawing the <see cref="Axis"/> tic marks.
        /// (<see cref="MinorTic.PenWidth"/> property). Units are in points (1/72 inch).
        /// </summary>
        public static float PenWidth = 1.0F;

        /// <summary>
        /// The display mode for the <see cref="Axis"/> major outside tic marks
        /// (<see cref="MinorTic.IsOutside"/> property).
        /// The major tic spacing is controlled by <see cref="Scale.MajorStep"/>.
        /// </summary>
        /// <value>true to show the major tic marks (outside the axis),
        /// false otherwise</value>
        public static bool IsOutside = true;

        /// <summary>
        /// The display mode for the <see cref="Axis"/> major inside tic marks
        /// (<see cref="MinorTic.IsInside"/> property).
        /// The major tic spacing is controlled by <see cref="Scale.MajorStep"/>.
        /// </summary>
        /// <value>true to show the major tic marks (inside the axis),
        /// false otherwise</value>
        public static bool IsInside = true;

        /// <summary>
        /// The display mode for the <see cref="Axis"/> major opposite tic marks
        /// (<see cref="MinorTic.IsOpposite"/> property).
        /// The major tic spacing is controlled by <see cref="Scale.MajorStep"/>.
        /// </summary>
        /// <value>true to show the major tic marks
        /// (inside the axis on the opposite side),
        /// false otherwise</value>
        public static bool IsOpposite = true;

        /// <summary>
        /// The default display mode for the <see cref="Axis"/> major outside
        /// "cross" tic marks (<see cref="MinorTic.IsCrossOutside"/> property).
        /// </summary>
        /// <remarks>
        /// The "cross" tics are a special, additional set of tic marks that
        /// always appear on the actual axis, even if it has been shifted due
        /// to the <see cref="Axis.Cross" /> setting.  The other tic marks are always
        /// fixed to the edges of the <see cref="Chart.Rect"/>.  The cross tics
        /// are normally not displayed, since, if <see cref="Axis.CrossAuto" /> is true,
        /// they will exactly overlay the "normal" and "inside" tics.  If
        /// <see cref="Axis.CrossAuto"/> is false, then you will most likely want to
        /// enable the cross tics.
        /// The major tic spacing is controlled by <see cref="Scale.MajorStep"/>.
        /// </remarks>
        /// <value>true to show the major cross tic marks, false otherwise</value>
        public static bool IsCrossOutside = false;

        /// <summary>
        /// The default display mode for the <see cref="Axis"/> major inside
        /// "cross" tic marks (<see cref="MinorTic.IsCrossInside"/> property).
        /// </summary>
        /// <remarks>
        /// The "cross" tics are a special, additional set of tic marks that
        /// always appear on the actual axis, even if it has been shifted due
        /// to the <see cref="Axis.Cross" /> setting.  The other tic marks are always
        /// fixed to the edges of the <see cref="Chart.Rect"/>.  The cross tics
        /// are normally not displayed, since, if <see cref="Axis.CrossAuto" /> is true,
        /// they will exactly overlay the "normal" and "inside" tics.  If
        /// <see cref="Axis.CrossAuto"/> is false, then you will most likely want to
        /// enable the cross tics.
        /// The major tic spacing is controlled by <see cref="Scale.MajorStep"/>.
        /// </remarks>
        /// <value>true to show the major cross tic marks, false otherwise</value>
        public static bool IsCrossInside = false;

        /// <summary>
        /// The default color for major tics (<see cref="MinorTic.Color"/> property).
        /// </summary>
        public static Color Color = Color.Black;
    }

    #endregion
}
